使用Spring test测试Controller

使用Spring test测试Controller

以前测试一个Contoller是否实现了相应的功能(包括DAO层是否正确工作),我们的做法是mvn clean package然后启动tomcat启动应用,然后打开浏览器(或者使用curl)访问一个URL,然后看webapp的日志输出,据此判断功能是否实现了启。动tomcat好累。或者有时候写个Main方法测试有的功能,太low了。

是时候使用Spring test了。

MockMvc初识

MockMvc是Main entry point for server-side Spring MVC test support。只有一个方法 perform, 我们正是通过他来执行我们的各种get,post方法,返回一个ResultActions,然后可以通过ResultActions来链式的执行各种动作。ResultActions提供了三个方法:

return type method desc
ResultActions andDo(ResultHandler handler) Perform a general action.
ResultActions andExpect(ResultMatcher matcher) Perform an expectation.
MvcResult andReturn() Return the result of the executed request for direct access to the results.

测试的目的无非就是清楚我们的Controller映射的方法能够正确处理请求,并且设置了modle,返回了view,从而可以把下面的DAO层都串联起来,及早发现问题。

接下来会通过Spring test的print() ResultHandler来打印出测试过程中一个请求的处理详情。重要的有请求的方法,参数,URL,映射的handler的方法,响应的状态码。

测试Controller

下面没有罗列代码,只是放了执行的具体信息,从中可以看到自己的Conroller中方法实现是否正确。完整代码

测试普通的Get请求及参数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MockHttpServletRequest:
HTTP Method = GET
Request URI = /spitter
Parameters = {new=[value]}

Handler:
Type = com.vonzhou.spitter.controller.SpitterController
Method = public java.lang.String com.vonzhou.spitter.controller.SpitterController.createSpitterProfile(org.springframework.ui.Model)

ModelAndView:
View name = spitters/edit
View = null
Attribute = spitter
value = com.vonzhou.spitter.persistence.Spitter@7ba4f

MockHttpServletResponse:
Status = 200
Forwarded URL = spitters/edit

测试返回JSON

下面是测试getSpitterInJson的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
MockHttpServletRequest:
HTTP Method = GET
Request URI = /spitter/json/test

Handler:
Type = com.vonzhou.spitter.controller.SpitterController
Method = public com.vonzhou.spitter.persistence.Spitter com.vonzhou.spitter.controller.SpitterController.getSpitterInJson()

MockHttpServletResponse:
Status = 200
Error message = null
Headers = {Content-Type=[application/json;charset=UTF-8]}
Content type = application/json;charset=UTF-8
Body = {"id":100,"username":"vonzhou","password":null,"fullName":null,"spittles":null,"email":null,"updateByEmail":false}

测试ModelAndView

下面是测试showSpitterProfile的情况

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
MockHttpServletRequest:
HTTP Method = GET
Request URI = /spitter/chown2

Handler:
Type = com.vonzhou.spitter.controller.SpitterController
Method = public java.lang.String com.vonzhou.spitter.controller.SpitterController.showSpitterProfile(java.lang.String,org.springframework.ui.Model)

ModelAndView:
View name = spitters/view
View = null
Attribute = spitter
value = com.vonzhou.spitter.persistence.Spitter@f71c7eaa
errors = []

MockHttpServletResponse:
Status = 200
Forwarded URL = spitters/view

测试上传文件(multipart/form-data类型)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
七月 24, 2016 2:21:05 下午 com.vonzhou.spitter.controller.SpitterController uploadImage
信息: Spitter name: vonzhou, desc: a student
七月 24, 2016 2:21:05 下午 com.vonzhou.spitter.controller.SpitterController uploadImage
信息: Spitter avatar file :1.jpeg

MockHttpServletRequest:
HTTP Method = POST
Request URI = /spitter/upload
Parameters = {name=[vonzhou], desc=[a student]}
Headers = {Content-Type=[multipart/form-data]}

Handler:
Type = com.vonzhou.spitter.controller.SpitterController
Method = public java.lang.String com.vonzhou.spitter.controller.SpitterController.uploadImage(java.lang.String,java.lang.String,org.springframework.web.multipart.MultipartFile)

ModelAndView:
View name = spitters/view

MockHttpServletResponse:
Status = 200
Forwarded URL = spitters/view

上面使用的都是使用 andDo执行 print 这个动作,全过程由我们自己去查看,当然也可以使用 andExpect 执行一次期待, 也就是看结果是否与我们的期待匹配。

问题记录

javax.servlet-api的版本要3.0以上,否则java.lang.NoClassDefFoundError: javax/servlet/SessionCookieConfig

Spring文档中说明了这一点:

Spring Framework 4.0 is now focused primarily on Servlet 3.0+ environments. If you are using the Spring MVC Test Framework you will need to ensure that a Servlet 3.0 compatible JAR is in your test classpath.